/**************************************************************************************************
* Filename:			InputManager.h
* Date:				03/05/10
* Mod. Date:		05/16/10
* Mod. Initials:	MG
* Author:			Malcolm J. Gruber
* Purpose:			A system used to manage input, and allow multiple inputs for the same
* 					container.
**************************************************************************************************/

#ifndef _INPUT_MANAGER_H_
#define _INPUT_MANAGER_H_

#ifndef NULL
#define NULL (0L)
#endif

#include "../Generic/DList.h"
#include "DirectInput.h"

class InputManager
{
private:
	class InputContainer
	{
	private:
		DList<unsigned char>	m_lKeyboard;
		DList<unsigned char>	m_lMouse;

		char m_uInputString[32];

	public:

		/*************************************************************************
		* InputContainer():				Constructor for InputContainer
		*
		* Mod. Date:					04/05/10
		* Mod. Initials:				MG
		*************************************************************************/
		InputContainer(void);
		/*************************************************************************
		* ~InputContainer():			Destructor for InputContainer
		*
		* Mod. Date:					04/05/10
		* Mod. Initials:				MG
		*************************************************************************/
		~InputContainer(void);

		/*************************************************************************
		* InputDown():					Checks to see if the desired input is
		*								being held down.
		*
		* Ins:							void
		*
		* Outs:							void
		*
		* Returns:						bool
		*
		* Mod. Date:					04/05/10
		* Mod. Initials:				MG
		*************************************************************************/
		bool InputDown(void);
		/*************************************************************************
		* InputPressed():				Checks to see if the desired input is
		*								pressed.
		*
		* Ins:							void
		*
		* Outs:							void
		*
		* Returns:						bool
		*
		* Mod. Date:					04/05/10
		* Mod. Initials:				MG
		*************************************************************************/
		bool InputPressed(void);
		/*************************************************************************
		* InputPressedEx():				Checks to see if the desired buffered 
		*								input is pressed.
		*
		* Ins:							void
		*
		* Outs:							void
		*
		* Returns:						bool
		*
		* Mod. Date:					04/05/10
		* Mod. Initials:				MG
		*************************************************************************/
		bool InputPressedEx(void);
		/*************************************************************************
		* InputUp():					Checks to see if the desired input is up.
		*
		* Ins:							void
		*
		* Outs:							void
		*
		* Returns:						bool
		*
		* Mod. Date:					04/05/10
		* Mod. Initials:				MG
		*************************************************************************/
		bool InputUp(void);
		/*************************************************************************
		* InputReleased():				Checks to see if the desired input is
		*								released.
		*
		* Ins:							void
		*
		* Outs:							void
		*
		* Returns:						bool
		*
		* Mod. Date:					04/05/10
		* Mod. Initials:				MG
		*************************************************************************/
		bool InputReleased(void);
		/*************************************************************************
		* InputReleasedEx():			Checks to see if the desired buffered 
		*								input is released.
		*
		* Ins:							void
		*
		* Outs:							void
		*
		* Returns:						bool
		*
		* Mod. Date:					04/05/10
		* Mod. Initials:				MG
		*************************************************************************/
		bool InputReleasedEx(void);

		/*************************************************************************
		* AddMouse():					Adds a mouse input value to the
		*								mouse input value list.
		*
		* Ins:							unsigned char uInput
		*
		* Outs:							void
		*
		* Returns:						void
		*
		* Mod. Date:					03/10/10
		* Mod. Initials:				MG
		*************************************************************************/
		void AddMouse(unsigned char uInput);
		/*************************************************************************
		* AddKeyboard():				Adds a keyboard input value to the 
		*								keyboard input value list.
		*
		* Ins:							unsigned char uInput
		*
		* Outs:							void
		*
		* Returns:						void
		*
		* Mod. Date:					03/10/10
		* Mod. Initials:				MG
		*************************************************************************/
		void AddKeyboard(unsigned char uInput);
		
		/*************************************************************************
		* GetInputString():				Retrieves the string of the input 
		*								container.
		*
		* Ins:							void
		*
		* Outs:							void
		*
		* Returns:						const char*
		*
		* Mod. Date:					03/10/10
		* Mod. Initials:				MG
		*************************************************************************/
		const char *GetInputString(void);
		/*************************************************************************
		* SetString():					Sets the string of the input container.
		*
		* Ins:							const char*
		*
		* Outs:							void
		*
		* Returns:						void
		*
		* Mod. Date:					03/10/10
		* Mod. Initials:				MG
		*************************************************************************/
		void SetString(const char *cString);
	};

	DList<InputContainer>	m_lInput;
	static InputManager	m_Instance;
	DirectInput*			m_DI;
	HWND					m_hWnd;
	long					m_MouseX;
	long					m_MouseY;
	long					m_WinMouseX;
	long					m_WinMouseY;
	POINT					m_Min;
	POINT					m_Max;
	
	/*************************************************************************
	* InputManager():				Constructor for InputManager
	*
	* Mod. Date:					03/10/10
	* Mod. Initials:				MG
	*************************************************************************/
	InputManager(void);
	InputManager(const InputManager&);
	InputManager& operator =(const InputManager&);
	/*************************************************************************
	* ~InputManager():				Destructor for InputManager
	*
	* Mod. Date:					03/10/10
	* Mod. Initials:				MG
	*************************************************************************/
	~InputManager(void);

	char* ToLowerCase(char* cString);

	/*************************************************************************
	* BindMouse():					Bounds the mouse inside the min and max.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						void
	*
	* Mod. Date:					05/16/10
	* Mod. Initials:				MG
	*************************************************************************/
	void BindMouse(void);
public:
	/*************************************************************************
	* GetInstance():				Returns the instance of the input 
	*								manager.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						const char*
	*
	* Mod. Date:					03/10/10
	* Mod. Initials:				MG
	*************************************************************************/
	static InputManager* GetInstance(void);

	/*************************************************************************
	* InitInputManager():			Initiate the input manager, taking in a 
	*								handle and instance to the window.
	*								Device flags:
	*									DIK_KEYBOARD
	*									DIK_MOUSE
	*
	* Ins:							HWND hWnd
	*								HINSTANCE hInstance
	*								int32_t unDevices
	*								int32_t unExclusive
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					03/10/10
	* Mod. Initials:				MG
	*************************************************************************/
	bool Initialize(HWND hWnd, HINSTANCE hInstance, int32_t unDevices, int32_t unExclusive = 0);
	/*************************************************************************
	* ShutdownInputManager():		Shuts down the input manager
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						void
	*
	* Mod. Date:					03/10/10
	* Mod. Initials:				MG
	*************************************************************************/
	void Shutdown(void);

	/*************************************************************************
	* UpdateDevices():				Updates the image of all input devices.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						void
	*
	* Mod. Date:					03/10/10
	* Mod. Initials:				MG
	*************************************************************************/
	void UpdateDevices(void);

	/*************************************************************************
	* InputDown():					Checks to see if the desired input is
	*								being held down.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					04/05/10
	* Mod. Initials:				MG
	*************************************************************************/
	bool InputDown(const char* Input);
	/*************************************************************************
	* InputPressed():					Checks to see if the desired input is
	*								being pressed.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					04/05/10
	* Mod. Initials:				MG
	*************************************************************************/
	bool InputPressed(const char* Input);
	/*************************************************************************
	* InputPressedEx():				Checks to see if the desired buffered
	*								input is being held down.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					04/05/10
	* Mod. Initials:				MG
	*************************************************************************/
	bool InputPressedEx(const char* Input);
	/*************************************************************************
	* InputUp():					Checks to see if the desired input is
	*								not pressed.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					04/05/10
	* Mod. Initials:				MG
	*************************************************************************/
	bool InputUp(const char* Input);
	/*************************************************************************
	* InputReleased():				Checks to see if the desired input is 
	*								released.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					04/05/10
	* Mod. Initials:				MG
	*************************************************************************/
	bool InputReleased(const char* Input);
	/*************************************************************************
	* InputReleasedEx():			Checks to see if the desired buffered 
	*								input is released.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					04/05/10
	* Mod. Initials:				MG
	*************************************************************************/
	bool InputReleasedEx(const char* Input);

	/*************************************************************************
	* GetWinMouseX():				Returns the X position of the mouse. (Win)
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					05/16/10
	* Mod. Initials:				MG
	*************************************************************************/
	int GetWinMouseX(void);
	/*************************************************************************
	* GetWinMouseY():				Returns the Y position of the mouse. (Win)
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					05/16/10
	* Mod. Initials:				MG
	*************************************************************************/
	int GetWinMouseY(void);
	/*************************************************************************
	* GetMouseX():					Returns the X position of the mouse.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					03/10/10
	* Mod. Initials:				MG
	*************************************************************************/
	int GetMouseX(void);
	/*************************************************************************
	* GetMouseY():					Returns the Y position of the mouse.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					03/10/10
	* Mod. Initials:				MG
	*************************************************************************/
	int GetMouseY(void);
	/*************************************************************************
	* SetMouseX():					Sets the X position of the mouse.
	*
	* Ins:							int mouseX
	*
	* Outs:							void
	*
	* Returns:						void
	*
	* Mod. Date:					05/16/10
	* Mod. Initials:				MG
	*************************************************************************/
	void SetMouseX(int mouseX);
	/*************************************************************************
	* SetMouseY():					Sets the Y position of the mouse.
	*
	* Ins:							int mouseY
	*
	* Outs:							void
	*
	* Returns:						void
	*
	* Mod. Date:					05/16/10
	* Mod. Initials:				MG
	*************************************************************************/
	void SetMouseY(int mouseY);
	/*************************************************************************
	* GetMouseSpeedX():				Returns the speed of the mouse along the
	*								X axis.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					03/10/10
	* Mod. Initials:				MG
	*************************************************************************/
	int GetMouseSpeedX(void);
	/*************************************************************************
	* GetMouseSpeedY():				Returns the speed of the mouse along the
	*								Y axis.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					03/10/10
	* Mod. Initials:				MG
	*************************************************************************/
	int GetMouseSpeedY(void);
	/*************************************************************************
	* GetMouseScrollSpeed():		Returns the speed of the mouses
	*								scrollwheel.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					03/10/10
	* Mod. Initials:				MG
	*************************************************************************/
	int GetMouseScrollSpeed(void);

	/*************************************************************************
	* AddMouse():					Adds a mouse input value to the
	*								mouse input value list with the correct
	*								string if it already exist, if not,
	*								creates a new string.
	*
	* Ins:							const char* cString
	*								unsigned char uInput
	*
	* Outs:							void
	*
	* Returns:						void
	*
	* Mod. Date:					04/05/10
	* Mod. Initials:				MG
	*************************************************************************/
	void AddMouse(const char* cString, unsigned char uInput);
	/*************************************************************************
	* AddKeyboard():				Adds a keyboard input value to the
	*								keyboard input value list with the correct
	*								string if it already exist, if not,
	*								creates a new string.
	*
	* Ins:							const char* cString
	*								unsigned char uInput
	*
	* Outs:							void
	*
	* Returns:						void
	*
	* Mod. Date:					04/05/10
	* Mod. Initials:				MG
	*************************************************************************/
	void AddKeyboard(const char* cString, unsigned char uInput);

	/*************************************************************************
	* ClearInput():					Clears out all input.
	*
	* Ins:							void
	*
	* Outs:							void
	*
	* Returns:						void
	*
	* Mod. Date:					04/05/10
	* Mod. Initials:				MG
	*************************************************************************/
	void ClearInput(void)
	{
		m_lInput.RemoveAll();
	}

	/*************************************************************************
	* MouseInside():				Check to see if the mouse is inside the
	*								rectangle.
	*
	* Ins:							Rect& section
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					05/16/10
	* Mod. Initials:				MG
	*************************************************************************/
	bool MouseInside(const RECT &section);
	/*************************************************************************
	* MouseInside():				Check to see if the mouse is inside the
	*								circle.
	*
	* Ins:							POINT &center
	*								float radius
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					05/16/10
	* Mod. Initials:				MG
	*************************************************************************/
	bool MouseInside(const POINT &center, float radius);
	/*************************************************************************
	* SetMouseBounds():				Sets the max for mouse to move.
	*
	* Ins:							long minX
	*								long minY
	*								long maxX
	*								long maxY
	*
	* Outs:							void
	*
	* Returns:						bool
	*
	* Mod. Date:					05/16/10
	* Mod. Initials:				MG
	*************************************************************************/
	void SetMouseBounds(long minX, long minY, long maxX, long maxY);


	/*************************************************************************
	* SetMouseSensitivity():	Sets the sensitivty of mouse movement.
	* Ins:								int nSensValue
	* Outs:							void
	* Returns:						void
	* Mod. Date:					06/13/10
	* Mod. Initials:				EK
	*************************************************************************/
	void SetMouseSensitivity( int nSensValue );
	/*************************************************************************
	* GetMouseSensitivity():	Gets the sensitivty of mouse movement.
	* Ins:								void
	* Outs:							void
	* Returns:						int
	* Mod. Date:					06/13/10
	* Mod. Initials:				EK
	*************************************************************************/
	int GetMouseSensitivity( void );
};

#endif // _INPUT_MANAGER_H_